package com.ssy.lingxi.platform.manage.serviceimpl.content;

import cn.hutool.core.util.StrUtil;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.platform.manage.constant.ShelfEnum;
import com.ssy.lingxi.platform.manage.entity.content.MemberNotice;
import com.ssy.lingxi.platform.manage.entity.content.QMemberNotice;
import com.ssy.lingxi.platform.manage.model.request.common.CommonIdRequest;
import com.ssy.lingxi.platform.manage.model.request.common.CommonStatusRequest;
import com.ssy.lingxi.platform.manage.model.request.content.ColumnTypeRequest;
import com.ssy.lingxi.platform.manage.model.request.content.MemberNoticePageRequest;
import com.ssy.lingxi.platform.manage.model.request.content.MemberNoticeRequest;
import com.ssy.lingxi.platform.manage.repository.MemberNoticeRepository;
import com.ssy.lingxi.platform.manage.service.content.IMemberNoticeService;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 内容能力-公告管理
 * @author wyx
 * @version 2.0.0
 * @date 2021-09-28
 */
@Service
public class MemberNoticeServiceImpl implements IMemberNoticeService {

    @Resource
    private JPAQueryFactory jpaQueryFactory;
    @Resource
    private MemberNoticeRepository memberNoticeRepository;


    /**
     * 公告分页列表
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberNotice>> page(MemberNoticePageRequest request, UserLoginCacheDTO user) {
        //表实体
        QMemberNotice qMemberNotice = QMemberNotice.memberNotice;
        //构造查询条件
        BooleanBuilder predicates = new BooleanBuilder();

        predicates.and(qMemberNotice.memberId.eq(user.getMemberId()));
        predicates.and(qMemberNotice.memberRoleId.eq(user.getMemberRoleId()));
        if (StrUtil.isNotBlank(request.getTitle())) {
            predicates.and(qMemberNotice.title.like("%" + request.getTitle() + "%"));
        }
        if (request.getColumnType() != null) {
            predicates.and(qMemberNotice.columnType.eq(request.getColumnType()));
        }
        if (request.getStatus() != null) {
            predicates.and(qMemberNotice.status.eq(request.getStatus()));
        }
        if (request.getStartTime() != null) {
            predicates.and(qMemberNotice.createTime.goe(request.getStartTime()));
        }
        if (request.getEndTime() != null) {
            predicates.and(qMemberNotice.createTime.loe(request.getEndTime()));
        }

        JPAQuery<MemberNotice> query = jpaQueryFactory.select(qMemberNotice).from(qMemberNotice).where(predicates);

        long totalCount = query.fetchCount();

        List<MemberNotice> list = query.orderBy(qMemberNotice.id.desc()).offset(request.getCurrentOffset()).limit(request.getPageSize()).fetch();

        return Wrapper.success(new PageData<>(totalCount, list));
    }

    /**
     * 公告详情
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberNotice> get(CommonIdRequest request) {
        MemberNotice memberNotice = memberNoticeRepository.findById(request.getId()).orElse(null);
        if (memberNotice == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        return Wrapper.success(memberNotice);
    }

    /**
     * 新增公告
     * @param request 请求参数
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> add(MemberNoticeRequest request, UserLoginCacheDTO user) {
        MemberNotice memberNotice = new MemberNotice();
        BeanUtils.copyProperties(request, memberNotice);
        memberNotice.setMemberId(user.getMemberId());
        memberNotice.setMemberRoleId(user.getMemberRoleId());
        memberNoticeRepository.saveAndFlush(memberNotice);
        return Wrapper.success();
    }

    /**
     * 修改公告
     * @param request 请求参数
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> update(MemberNoticeRequest request, UserLoginCacheDTO user) {
        MemberNotice memberNotice = memberNoticeRepository.findById(request.getId()).orElse(null);
        if (memberNotice == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        if (memberNotice.getStatus().equals(ShelfEnum.ON_SHELF.getCode())) {
            throw new BusinessException(ResponseCode.MAN_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }
        BeanUtils.copyProperties(request, memberNotice);
        memberNoticeRepository.saveAndFlush(memberNotice);
        return Wrapper.success();
    }

    /**
     * 上架/下架
     * @param request 请求参数
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> updateStatus(CommonStatusRequest request, UserLoginCacheDTO user) {
        MemberNotice memberNotice = memberNoticeRepository.findById(request.getId()).orElse(null);
        if (memberNotice == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        memberNotice.setStatus(request.getShelfStatus());
        memberNoticeRepository.saveAndFlush(memberNotice);
        return Wrapper.success();
    }

    /**
     * 删除公告
     * @param request 请求参数
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> delete(CommonIdRequest request, UserLoginCacheDTO user) {
        MemberNotice memberNotice = memberNoticeRepository.findById(request.getId()).orElse(null);
        if (memberNotice == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        if (memberNotice.getStatus().equals(ShelfEnum.ON_SHELF.getCode())) {
            throw new BusinessException(ResponseCode.MAN_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }
        memberNoticeRepository.delete(memberNotice);
        return Wrapper.success();
    }

    /**
     * 根据栏目获取所有公告
     * @param columnType 栏目类型： 1-会员首页公告 2-注册须知 3-入库协议
     * @return 操作结果
     */
    @Override
    public Wrapper<List<MemberNotice>> findAllByColumnType(Integer columnType, UserLoginCacheDTO user) {
        List<MemberNotice> list = memberNoticeRepository.findAllByMemberIdAndMemberRoleIdAndStatusAndColumnType(user.getMemberId(), user.getMemberRoleId(), ShelfEnum.ON_SHELF.getCode(), columnType, Sort.by(Sort.Direction.DESC, "createTime"));
        return Wrapper.success(list);
    }

    /**
     * 获取最新公告
     * @param pageVO 分页参数
     * @return 操作结果
     */
    @Override
    public Wrapper<PageData<MemberNotice>> findNewestNotice(PageVO pageVO, UserLoginCacheDTO user) {
        //表实体
        QMemberNotice qMemberNotice = QMemberNotice.memberNotice;
        //构造查询条件
        JPAQuery<MemberNotice> query = jpaQueryFactory.select(qMemberNotice)
                .from(qMemberNotice)
                .where(qMemberNotice.memberId.eq(user.getMemberId()).and(qMemberNotice.memberRoleId.eq(user.getMemberRoleId()))
                        .and(qMemberNotice.status.eq(2)).and(qMemberNotice.columnType.eq(1)));

        long totalCount = query.fetchCount();
        List<MemberNotice> noticeList = query.orderBy(qMemberNotice.top.desc(), qMemberNotice.createTime.desc()).fetch();

        return Wrapper.success(new PageData<>(totalCount, noticeList));
    }

    /**
     * 根据栏目和会员信息获取所有公告
     * @param columnTypeRequest 请求参数
     * @return 操作结果
     */
    @Override
    public Wrapper<List<MemberNotice>> findByColumnTypeMemberInfo(ColumnTypeRequest columnTypeRequest) {
        List<MemberNotice> list = memberNoticeRepository.findAllByMemberIdAndMemberRoleIdAndStatusAndColumnType(columnTypeRequest.getMemberId(), columnTypeRequest.getRoleId(), ShelfEnum.ON_SHELF.getCode(), columnTypeRequest.getColumnType(), Sort.by(Sort.Direction.DESC, "createTime"));
        return Wrapper.success(list);
    }
}
